package org.itboys.mobile.service.mongo.mobile;


import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.apache.commons.lang.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.encryption.Digests;
import org.itboys.commons.utils.image.ImageUtils;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.framework.resource.ResourceHolder;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.product.SundayProductMapper;
import org.itboys.mobile.dto.SundayCommentDto;
import org.itboys.mobile.dto.SundayMemberDto;
import org.itboys.mobile.dto.score.SundayMemberFinanceDto;
import org.itboys.mobile.entity.mongo.SundayMember;
import org.itboys.mobile.entity.mysql.product.SundayProduct;
import org.itboys.mobile.entity.mysql.wallet.PearlWalletConsumeRecord;
import org.itboys.mobile.service.mongo.mobile.collection.SundayMobileCollectionService;
import org.itboys.mobile.service.mysql.mobile.wallet.PearlWalletService;
import org.itboys.mobile.util.NameUtil;
import org.itboys.mobile.util.NumberUtil;
import org.itboys.mongodb.core.MongoDataSource;
import org.itboys.mongodb.service.BaseMongoService;
import org.itboys.mongodb.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 作者：jiangxiong
 * 日期：2017年5月8日
 * 联系方式 ：empty90911@126.com
 * 描述：圣代_用户_service
 */
@Service
public class SundayMobileMemberService extends BaseService<SundayMember,Long> {

    @Autowired
    private SundayMobileCodeService codeService;
    @Autowired
    private SundayMobileCidService cidService;
    @Autowired
    private ResourceHolder resourceHolder;
    @Autowired
    private SundayMobileCommentService commentService;

    @Autowired
    private SundayMobileCollectionService collectionService;
    @Autowired
    private SundayProductMapper productMapper;

    private PearlWalletService walletService;

    @Resource(name = "mobileDs")
    private MongoDataSource kitchenDataSource;
    @Override
    protected MongoDataSource getMongoDataSource() {
        return kitchenDataSource;
    }

    @Override
    protected Class<SundayMember> getEntityClass() {
        return SundayMember.class;
    }



    /**
     * 用户注册（手机号+密码）。逻辑自定义。
     * @param mobile
     * @param code
     * @param password
     * @return
     */
    public SundayMemberDto register(String mobile,String password, String code){
        //2017年6月20日，新增，验证签名
        Map<String, Object> param =new HashMap<String,Object>();


        //校验验证码。
     int check_code=codeService.checkCode(mobile,code, SundayCommonConstants.validate_code_type_register);
     if(check_code!=0){
         ///throw new ErrorException("验证码错误。");
     }
        //校验用户
      param.clear();
        param.put("isDeleted",0);
        //实际校验mobile字段
        param.put("mobile",mobile);
        List<SundayMember> oldMembers = super.list(param);
        if(ListUtil.isNotNull(oldMembers)){
            throw new ErrorException("此手机号已被注册。");
        }
        SundayMember member = new SundayMember();
        member.setIsDeleted(0);
        member.setStatus(0);
        member.setUserName(NumberUtil.generateNumber("APP"));
        member.setUserType(SundayCommonConstants.user_type_member);
        member.setMobile(mobile);
        member.setNickName(NameUtil.getRandomName());
        member.setImage(NameUtil.getRandomLogo());

        member.setPassword(Digests.md5(password));
        //member.setParentId(0l);
        super.save(member);
        //初始化用户其他信息
        initOtherInfo(member);
        //返回用户信息
        SundayMemberDto memberDto=packageDtoSingle(member);
        //设置用户的token。暂时是用户的秘密
      //  memberDto.setToken(member.getPassword());
         return memberDto;
    }

    /**
     * 登陆。手机号和密码登录.
     *
     * @param mobile。。
     * @param password
     * @return
     */
    public SundayMemberDto login(String mobile, String password,Integer loginType){
        //2017年6月20日，新增，验证签名
        Map<String, Object> param =new HashMap<String,Object>();
        /*param.put("mobile",mobile);
        param.put("password",password);
        param.put("loginType",loginType);
        param.put("nonce", nonce);
        param.put("sign", sign);
        boolean signSer = MobileSignUtils.signCheck(param, sign);
        if(!signSer){
            logger.warn("签名校验失败");
            throw new ErrorException("签名校验失败");
        }*/
        //查找用户
        param.clear();
        param.put("isDeleted", 0);
        param.put("mobile", mobile);
        param.put("password", Digests.md5(password));
        if(loginType==1){
            param.put("userType", SundayCommonConstants.user_type_member);
        }
        if(loginType==2){
            List<Integer> userTypes = new ArrayList<Integer>();
            userTypes.add(SundayCommonConstants.user_type_business);
          //  userTypes.add(SundayCommonConstants.user_type_customer);
            param.put("userType in", userTypes);
        }
        List<SundayMember> members = super.list(param);
        if (ListUtil.isNull(members)) {
            throw new ErrorException("账户或密码错误");

        }
        SundayMember member=members.get(0);
        if (member.getStatus()!=0) {
            throw new ErrorException("账户被冻结");

        }
        SundayMemberDto memberDto=packageDtoSingle(member);
        //设置用户的token。暂时是用户的秘密
        //memberDto.setToken(member.getPassword());

        return memberDto;
    }




    /**
     * 第三方登陆,第一步。只传入第三方信息。农厨第三方登陆需要绑定手机号和小区
     * @param thirdType
     * @param unionId
     * @return
     */
    public SundayMemberDto loginWithThirdOne(Integer thirdType,String unionId){
        //2017年6月20日，新增，验证签名
        Map<String, Object> param =new HashMap<String,Object>();
       /* param.put("thirdType",thirdType);
        param.put("unionId",unionId);
        param.put("nonce", nonce);
        param.put("sign", sign);
        boolean signSer = MobileSignUtils.signCheck(param, sign);
        if(!signSer){
            logger.warn("签名校验失败");
            throw new ErrorException("签名校验失败");
        }*/

        //校验用户
      param.clear();
        param.put("isDeleted",0);
        //校验第三方unionId
        if(thirdType==SundayCommonConstants.third_type_weixin){
            param.put("weixinUnionId",unionId);
        }else if(thirdType==SundayCommonConstants.third_type_qq){
            param.put("qqUnionId",unionId);
        }else if(thirdType==SundayCommonConstants.third_type_weibo){
            param.put("weiboUnionId",unionId);
        }else{
             throw new ErrorException("登陆类型错误");
        }
        List<SundayMember> oldMembers = super.list(param);
        if(ListUtil.isNull(oldMembers)){

            //如果为空，调用第三方登陆，第二步
            return null;
        }



        return packageDtoSingle(oldMembers.get(0));
    }
    /**
     * 第三方登陆,第二步。传入第三方信息和手机号。农厨第三方登陆需要绑定手机号和小区
     * @param thirdType
     * @param unionId
     * @param mobile
     * @return
     */
    public SundayMemberDto loginWithThirdTwo(Integer thirdType,String nickName,String image, String unionId, String mobile,String code) {

        //检验验证码
        int reulct_code =codeService.checkCode(mobile,code,SundayCommonConstants.validate_code_type_login);
        if(reulct_code!=0){
            throw new ErrorException("验证码错误");
        }
        //校验用户
        Map<String,Object> param = new HashMap<String,Object>();
        param.put("isDeleted",0);
        param.put("mobile",mobile);
        //校验第三方unionId
        /*if(thirdType==SundayCommonConstants.third_type_weixin){
            param.put("weixinUnionId",unionId);
        }else if(thirdType==SundayCommonConstants.third_type_qq){
            param.put("qqUnionId",unionId);
        }else if(thirdType==SundayCommonConstants.third_type_weibo){
            param.put("weiboUnionId",unionId);
        }else{
            throw new ErrorException("登陆类型错误");
        }*/
        List<SundayMember> oldMembers = super.list(param);
        if(ListUtil.isNull(oldMembers)){
            //如果为空，调用第三方登陆，第三步
            return null;
        }
        //获取第三方信息。头像，昵称，unionId。替换用户的信息
        SundayMember member = oldMembers.get(0);
        member.setNickName(nickName);
        //保存unionId
        if(thirdType==SundayCommonConstants.third_type_weixin){
            member.setWeixinUnionId(unionId);
        }else if(thirdType==SundayCommonConstants.third_type_qq){
            member.setQqUnionId(unionId);
        }else if(thirdType==SundayCommonConstants.third_type_weibo){
            member.setWeiboUnionId(unionId);
        }
        //获取第三方头像。半链接
           String random=String.valueOf(new Date().getTime());
        //如果当前项目的上传文件目录下没有logo文件夹，请自行创建。此文件夹存放的是默认的头像和第三方登陆用户头像
        String savePath = resourceHolder.getStringValue("fileUploadPath")+"/logo/"+random+".jpg";
       ImageUtils.buildImg(savePath,image);
       member.setImage("/logo/"+random+".jpg");
        super.updateExceptEmpty(member.getId(),member);
        SundayMemberDto memberDto=packageDtoSingle(member);

        return memberDto;
    }

    /**
     * 第三方登陆,第三步。传入第三方信息，手机号，密码，小区信息。农厨第三方登陆需要绑定手机号和小区
     * @param thirdType
     * @param nickName
     * @param image
     * @param unionId
     * @param mobile
     * @param code
     * @param password
     * @param villageId
     * @return
     */
    public SundayMemberDto loginWithThirdThree(Integer thirdType,String nickName,String image, String unionId, String mobile,String code,String password,Long villageId) {
        //校验用户
        Map<String,Object> param = new HashMap<String,Object>();
        param.put("isDeleted",0);
        param.put("mobile",mobile);
        //校验第三方unionId
        if(thirdType==SundayCommonConstants.third_type_weixin){
            param.put("weixinUnionId",unionId);
        }else if(thirdType==SundayCommonConstants.third_type_qq){
            param.put("qqUnionId",unionId);
        }else if(thirdType==SundayCommonConstants.third_type_weibo){
            param.put("weiboUnionId",unionId);
        }else{
            throw new ErrorException("登陆类型错误");
        }
        List<SundayMember> oldMembers = super.list(param);
        SundayMember member = new SundayMember();
        //创建用户
        if(ListUtil.isNull(oldMembers)){
            member.setIsDeleted(0);
            member.setStatus(0);
            member.setUserName(NumberUtil.generateNumber("APP"));
            member.setUserType(SundayCommonConstants.user_type_member);
            member.setMobile(mobile);
            member.setNickName(nickName);
            //member.setParentId(0l);
            //获取第三方头像。半链接
            String random=String.valueOf(new Date().getTime());
            //如果当前项目的上传文件目录下没有logo文件夹，请自行创建。此文件夹存放的是默认的头像和第三方登陆用户头像
            String savePath = resourceHolder.getStringValue("fileUploadPath")+"/logo/"+random+".jpg";
            ImageUtils.buildImg(savePath,image);
            member.setImage("/logo/"+random+".jpg");
            //保存unionId
            if(thirdType==SundayCommonConstants.third_type_weixin){
                member.setWeixinUnionId(unionId);
            }else if(thirdType==SundayCommonConstants.third_type_qq){
                member.setQqUnionId(unionId);
            }else if(thirdType==SundayCommonConstants.third_type_weibo){
                member.setWeiboUnionId(unionId);
            }
            member.setPassword(Digests.md5(password));
            super.save(member);
            //初始化用户其他信息
            initOtherInfo(member);
        //返回用户信息。此步骤是避免接口端误操作第二步。
        }else{
            member=oldMembers.get(0);
        }
        SundayMemberDto memberDto=packageDtoSingle(member);
        //设置用户的token。暂时是用户的秘密
       // memberDto.setToken(member.getPassword());
        return memberDto;
    }

    /**
     * 退出登录。删除CID
     * @param memberId
     */
    public void logout(long memberId){
        cidService.clear(memberId);
    }
    /**
     * 修改个人信息
     * @param memberId
     * @param  nickName
     * @param mobileName
     * @param address
     * @param email
     * @param image
     * @param idCard
     * @param desc
     */
    public SundayMemberDto update(Long memberId,String nickName,String mobileName,String address,String email,
                                  String image,String idCard,String desc){

        SundayMember member = new SundayMember();
        member.setId(memberId);
        member.setNickName(nickName);
        member.setMobileName(mobileName);
        member.setAddress(address);
      //  member.setEmail(email);
        member.setImage(image);
       // member.setIdCard(idCard);
        member.setDesc(desc);
        super.updateExceptEmpty(memberId,member);
        return packageDtoSingle(super.getById(memberId));
    }

    /**
     * 获取用户详情
     * @param memberId
     * @return
     */
    public SundayMemberDto findOne(Long memberId){
        SundayMemberDto memberDto = packageDtoSingle(super.getById(memberId));
        //装载其他元素
        //是否收藏
        Integer isCollection =collectionService.checkIsCollection(memberId,SundayCommonConstants.collection_type_business,memberId);
        memberDto.setIsCollection(isCollection);
        //用户评价。装载5个
        List<SundayCommentDto> comments = commentService.getCommentByNumber(5,memberId,SundayMember.class.getSimpleName());
        memberDto.setComments(comments);
        //产品列表。所有。
      // .. List<Long> productIds =permissionService.getPermission(Long.valueOf(memberId),1);
        Map<String,Object> param = new HashMap<String, Object>();
        param.put("memberId",memberId);
        param.put("status",SundayCommonConstants.NO);
        param.put("type",SundayCommonConstants.type_mall);
        List<SundayProduct> oldProducts = productMapper.select(param);
        List<Map<String,Object>> products = new ArrayList<Map<String,Object>>();
        for(SundayProduct oldProduct:oldProducts){
            Map<String,Object> product = new HashMap<String, Object>();
            product.put("id",oldProduct.getId());
            product.put("name",oldProduct.getName()+oldProduct.getStandard());
            product.put("image",resourceHolder.getStringValue("imgRoot")+oldProduct.getImage());
            product.put("price",oldProduct.getPrice());
            product.put("marketPrice",oldProduct.getMarketPrice());
            products.add(product);
        }
        memberDto.setProducts(products);


        return memberDto;
    }

    public SundayMember getMemberInfo(SundayMember member){
        String imgRoot = resourceHolder.getStringValue("imgRoot");
        if (member.getMemberLevel()==2){
            if (StringUtils.isNotBlank(member.getShopLogo())){
                member.setShopLogo(imgRoot+member.getShopLogo());
            }
            if (StringUtils.isNotBlank(member.getShopImage())){
                member.setShopImage(imgRoot+member.getShopImage());
            }
            if (StringUtils.isNotBlank(member.getPath())){
                member.setPath(imgRoot+member.getPath());
            }
        }
        if (StringUtils.isBlank(member.getImage())){
            member.setImage(SundayCommonConstants.IMAGE_PATH);
        }
        if (member.getRecId()!=0){
            SundayMember mm = getById(member.getRecId());
            if (mm!=null){
                member.setRecName(mm.getShopName());
                if (StringUtils.isNotBlank(mm.getShopLogo())){
                    member.setRecLogo(imgRoot+mm.getShopLogo());
                }
            }
        }
        return member;
    }

    public SundayMember findByWeixinUnionId(String weixinUnionId){
        return getByField("weixinUnionId",weixinUnionId);
    }

    /**
     * 修改密码。使用旧密码
     * @param memberId
     * @param oldPassword
     * @param newPassword
     */
    public void updatePassword(Long memberId,String oldPassword,String newPassword){

       SundayMember member = super.getById(memberId);
        if (!Digests.md5(oldPassword).equalsIgnoreCase(member.getPassword())) {
            throw new ErrorException("旧密码错误");
        }
        super.update(memberId,"password",newPassword);
    }


    /**
     * 修改密码。使用验证码
     * @param memberId
     * @param mobile
     * @param newPassword
     * @param code
     */
    public void updatePasswordWithCode(Long memberId,String mobile,String newPassword,String code){
        //2017年6月20日，新增，验证签名
       Map<String, Object> param =new HashMap<String,Object>();
      /*   param.put("mobile",mobile);
        param.put("newPassword",newPassword);
        param.put("code",code);
        param.put("nonce", nonce);
        param.put("sign", sign);
        boolean signSer = MobileSignUtils.signCheck(param, sign);
        if(!signSer){
            logger.warn("签名校验失败");
            throw new ErrorException("签名校验失败");
        }*/
        //校验验证码。
        int check_code=codeService.checkCode(mobile,code, SundayCommonConstants.validate_code_type_update_password);
        if(check_code!=0){
            throw new ErrorException("验证码错误。");
        }
        param.clear();
        param.put("isDeleted", 0);
        param.put("mobile", mobile);
        List<SundayMember> members = super.list(param);
        if(ListUtil.isNotNull(members)){
            SundayMember member = members.get(0);
            super.update(member.getId(),"password",Digests.md5(newPassword));
        }
    }
    /**
     * 忘记密码。
     * @param mobile
     * @param newPassword
     * @param code
     */
    public void forgetPassword(String mobile,String newPassword,String code){
       //2017年6月20日，新增，验证签名
        Map<String, Object> param =new HashMap<String,Object>();
       /*  param.put("mobile",mobile);
        param.put("newPassword",newPassword);
        param.put("code",code);
        param.put("nonce", nonce);
        param.put("sign", sign);
        boolean signSer = MobileSignUtils.signCheck(param, sign);
        if(!signSer){
            logger.warn("签名校验失败");
            throw new ErrorException("签名校验失败");
        }*/
        //校验验证码。
        int check_code=codeService.checkCode(mobile,code, SundayCommonConstants.validate_code_type_forget_password);
        if(check_code!=0){
            throw new ErrorException("验证码错误。");
        }
      param.clear();
        param.put("isDeleted", 0);
        param.put("mobile", mobile);
        List<SundayMember> members = super.list(param);
        if(ListUtil.isNotNull(members)){
            SundayMember member = members.get(0);
            super.update(member.getId(),"password",Digests.md5(newPassword));
        }
    }

    /**
     * 设置支付宝密码
     * @param memberId
     * @param payPassword
     * @param code
     */
    public void setPayPassword(Long memberId,String payPassword,String code){
    /*    Map<String, Object> param =new HashMap<String,Object>();
        param.put("payPassword",payPassword);
        param.put("code",code);
        param.put("nonce", nonce);
        param.put("sign", sign);
        boolean signSer = MobileSignUtils.signCheck(param, sign);
        if(!signSer){
            logger.warn("签名校验失败");
            throw new ErrorException("签名校验失败");
        }*/
        SundayMember member =super.getById(memberId);
        logger.info("member_id="+member.getId()+",member_mobile="+member.getMobile());
        //校验验证码。
        int check_code=codeService.checkCode(member.getMobile(),code, SundayCommonConstants.validate_code_type_set_pay_password);
        if(check_code!=0){
            throw new ErrorException("验证码错误。");
        }
        super.update(member.getId(),"payPassword",Digests.md5(payPassword));
    }

    /**
     * 修改支付密码
     * @param memberId
     * @param newPayPassword
     * @param code
     */
    public void updatePayPassWord(Long memberId,String newPayPassword,String code){
        /*Map<String, Object> param =new HashMap<String,Object>();
        param.put("newPayPassword",newPayPassword);
        param.put("code",code);
        param.put("nonce", nonce);
        param.put("sign", sign);
        boolean signSer = MobileSignUtils.signCheck(param, sign);
        if(!signSer){
            logger.warn("签名校验失败");
            throw new ErrorException("签名校验失败");
        }*/
        SundayMember member =super.getById(memberId);
        //校验验证码。
        int check_code=codeService.checkCode(member.getMobile(),code, SundayCommonConstants.validate_code_type_update_pay_password);
        if(check_code!=0){
            throw new ErrorException("验证码错误。");
        }
        super.update(member.getId(),"payPassword",Digests.md5(newPayPassword));
    }

    /**
     * 校验支付密码
     * @param memberId
     * @param payPassword
     */
   public void checkPayPassWord(Long memberId,String payPassword){

        SundayMember member =super.getById(memberId);
        if(!StringUtils.isNotEmpty(member.getPayPassword())){
            throw new ErrorException("未设置支付密码");
        }
        if(!member.getPayPassword().equalsIgnoreCase(Digests.md5(payPassword))){
            throw new ErrorException("支付密码错误");
        }
    }

    /**
     * 用户创建时，自动创建用户的其他信息
     */
    public void initOtherInfo(SundayMember member){
        //创建用户积分主表
        //创建用户余额主表
        //创建用户小区(即收货地址)
     /* addressService.saveAddress(0l,member.getId(),villageId,member.getNickName(),member.getMobile(),
              null,null,null,null,null,null,null);
      //赠送优惠券
        promotionService.sendCouponByRegister(member.getId());*/
    }
    /**
     * 组装用户DTO。逻辑可以自定义
     */
    public SundayMemberDto packageDtoSingle(SundayMember member) {
        SundayMemberDto memberDto =new SundayMemberDto(
                member.getId(),member.getCreateTime(), member.getCreateDate(),
                member.getUserName(), member.getNickName(), member.getMobile(), member.getMobileName(), member.getAddress(), member.getEmail(),
                member.getUserType(),resourceHolder.getStringValue("imgRoot")+member.getImage(), member.getIdCard(), member.getBirthDay(),member.getSex(),
                member.getDesc(), member.getGrade().toString(), member.getBusinessType(), member.getBusinessTime()
                );

        memberDto.setShareUrl(resourceHolder.getStringValue("mobileRoot")+"/sunday/mobile/member/share?id="+member.getId());
        memberDto.setShareImage(memberDto.getImage());
        memberDto.setShareTitle("平安车行 用户推广");
        memberDto.setShareDesc("我是："+memberDto.getNickName()+",我为【平安车行】代言，快来加入吧");
        //设置用户的token。暂时是用户的秘密
       // memberDto.setToken(member.getPassword());
        return  memberDto;
    }
    public List<SundayMemberDto>  packageDtoMuilt( List<SundayMember> members) {
        List<SundayMemberDto> dtos = new ArrayList<SundayMemberDto>();
        for(SundayMember member:members){
            dtos.add( packageDtoSingle(member));
        }
        return dtos;
    }

    /**
     * ----------------会员卡相关------------------------
     */


    /**
     * 会员卡_查询积分、余额、折扣_映射到用户dto中，积分和余额
     */
    public SundayMemberFinanceDto getMemberFinance(Long memberId, SundayMember member){
        BigDecimal score =new BigDecimal("0");//用户剩余积分。用户DTO中体现
        BigDecimal balance=new BigDecimal("0");//用户剩余额。用户DTO中体现
         BigDecimal discount=new BigDecimal("1");//用户折扣。小于1的小数
         String status="";//会员卡状态。0未发卡,1已发卡,8挂失,9作废

        return new SundayMemberFinanceDto(score,  balance,  discount,  status);
    }

    /**
     * 获取记录的用户位置。如果为空，则默认读取杭州的经纬度
     * @param memberId
     * @return
     */
    public SundayMember getLocation(Long memberId){
        SundayMember member =super.getById(memberId);
        if(member.getLongitude()==null){
            member.setLongitude(120.159635);
        }
        if(member.getLatitude()==null){
            member.setLatitude(30.279328);
        }
        return member;
    }

    /**
     *
     */
    /**
     * 变更余额
     * @param memberId
     * @param type
     * @param orderNo
     * @param payAmount
     *
     * @param out_trade_no 充值成功后相关
     */
    public void changeBalance(Long memberId,
                              Integer type,
                              String orderNo,
                              BigDecimal payAmount,
                              List<PearlWalletConsumeRecord> walletRecords,
                              String out_trade_no){
        SundayMember member =super.getById(memberId);
        if(member.getUserType()==SundayCommonConstants.user_type_member){
            //生成本地充值记录

            walletService.generateRecord(memberId,
                    type,
                    orderNo,
                    payAmount,
                    walletRecords,
                    out_trade_no);



            //绑定了会员卡。将余额数据传入pos
            /*
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(member.getCardNo())){
                //余额变更类型
                if(type==SundayCommonConstants.income_record_type_charge||
                        type== SundayCommonConstants.income_record_type_free||
                        type== SundayCommonConstants.income_record_type_cancel){
                    posMemberService.addPosBalance(member.getCardNo(),payAmount,payAmount);
                }else if(type==SundayCommonConstants.income_record_type_consume){
                    posMemberService.deductionPosBalance(member.getCardNo(),payAmount,orderNo);
                }

            }
            */
        }

    }

}
